// [[ OnflowGenerator File UUID: c6de822af0604468a2c9e4d68d6d091f  ]]
package com.itdct.onflow.system.role.service

import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.itdct.onflow.core.constant.CommonString
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.extend.*
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.common.base.BaseSysService
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.extend.dict
import com.itdct.onflow.system.menu.mapper.SysMenuMapper
import com.itdct.onflow.system.role.entity.SysRoleEntity
import com.itdct.onflow.system.role.entity.SysRoleMenuEntity
import com.itdct.onflow.system.role.mapper.SysRoleMapper
import com.itdct.onflow.system.role.mapper.SysRoleMenuMapper
import com.itdct.onflow.system.role.qo.SysRoleEditQo
import com.itdct.onflow.system.role.qo.SysRoleSearchQo
import com.itdct.onflow.system.role.vo.SysRoleDetailVo
import com.itdct.onflow.system.role.vo.SysRoleListVo
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author DCTANT
 * @date 2025-09-02 16:19:43
 * @version 1.0
 * @description 系统角色服务
 */
@Service
class SysRoleService(
    val sysRoleMapper: SysRoleMapper,
    val sysRoleMenuMapper: SysRoleMenuMapper,
    val sysMenuMapper: SysMenuMapper
) : BaseSysService() {

    @Transactional(rollbackFor = [Exception::class])
    fun add(qo: SysRoleEditQo, context: Context): RespVo<Long> {
        val addEntity = qo.toEntity(SysRoleEntity::class.java)
        val id = sysRoleMapper.insertEx(addEntity)

        addRoleMenuRel(qo, id, addEntity)
        return success(id)
    }

    private fun addRoleMenuRel(qo: SysRoleEditQo, id: Long, addEntity: SysRoleEntity) {
        val sysRoleMenuEntities = ArrayList<SysRoleMenuEntity>()
        for (menuId in qo.menuIds) {
            val sysRoleMenuEntity = SysRoleMenuEntity()
            sysRoleMenuEntity.roleId = id
            sysRoleMenuEntity.menuId = menuId
            sysRoleMenuEntity.platformType = addEntity.platformType
            sysRoleMenuEntities.add(sysRoleMenuEntity)
        }
        sysRoleMenuMapper.saveBatch(sysRoleMenuEntities)
    }

    @Transactional(rollbackFor = [Exception::class])
    fun update(qo: SysRoleEditQo, context: Context): RespVo<Unit> {
        val updateEntity = sysRoleMapper.selectByIdEx(qo.id)
        qo.injectValue(updateEntity)
        sysRoleMapper.updateEx(updateEntity)

        // INFO: Zhouwx: 2025/9/15 删除之前的绑定关系
        sysRoleMenuMapper.deleteByRoleId(updateEntity.id!!)

        addRoleMenuRel(qo, updateEntity.id!!, updateEntity)
        return success()
    }

    fun delete(qo: SysRoleEditQo, context: Context): RespVo<Unit> {
        val ids = qo.ids ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_DELETE_ID_LIST)
        val deleteEntities = sysRoleMapper.selectByIdsEx(ids)
        sysRoleMapper.deleteBatchEx(deleteEntities)
        return success()
    }

    fun detail(qo: SysRoleSearchQo, context: Context): RespVo<SysRoleDetailVo> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val vo = sysRoleMapper.findById(id) ?: fail(CommonString.ENTITY_NOT_FOUND_USAGE("系统角色", id))

        val ktQueryWrapper = KtQueryWrapper(SysRoleMenuEntity::class.java)
        ktQueryWrapper.eq(SysRoleMenuEntity::roleId, id)
        val roleMenuEntities = sysRoleMenuMapper.selectList(ktQueryWrapper)
        val menuIds = roleMenuEntities.map { it.menuId }
        vo.menuIds.addAll(menuIds)

        return success(vo.dict())
    }

    fun page(qo: SysRoleSearchQo, context: Context): RespPageVo<SysRoleListVo> {
        startPage(context)
        val pageData = sysRoleMapper.findByList(qo)
        return successPage(pageData.dict())
    }

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]

    fun selectNameList(qo: SysRoleSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysRoleMapper.selectNameList(qo)
        return success(vos)
    }

    fun selectCodeList(qo: SysRoleSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysRoleMapper.selectCodeList(qo)
        return success(vos)
    }
// [[ OnflowGenerator Range (- selectFunctions -) End ]]
}